import path from 'path';

import log4js, { Configuration, Level, Logger } from 'log4js';

import { configure, HvigorLogger } from '../../log/hvigor-log.js';
import { MetricLogType } from '../../metrics/event/log-event.js';
import { DAEMON_LOG_PATH } from '../const/daemon-const.js';

const daemonConfiguration: Configuration = {
  appenders: {
    'daemon-file': {
      type: 'fileSync',
      filename: path.resolve(DAEMON_LOG_PATH, `daemon-${process.pid}.log`),
      maxLogSize: 10 * 1024 * 1024,
      backups: 2,
      encoding: 'utf-8',
    },
  },
  categories: {
    daemon: { appenders: ['daemon-file'], level: 'debug' },
  },
};

export class HvigorDaemonLogger extends HvigorLogger {
  private readonly _daemonFileLogger: Logger;

  protected constructor(category?: string) {
    super('default');
    this._daemonFileLogger = log4js.getLogger(category);
  }

  /**
   * 获取对于类别的HvigorLogger实例
   *
   * @param {string} category 默认是default
   * @return {HvigorLogger}
   */
  public static getLogger(category?: string): HvigorDaemonLogger {
    return this.getInstance(HvigorDaemonLogger, category);
  }

  log(level: Level | string, ...args: unknown[]): void {
    this.createLogEventByDurationId(level, MetricLogType.INFO, ...args);
    this._daemonFileLogger.log(level, ...args);
  }

  debug(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.DEBUG, ...args);
    this._daemonFileLogger.debug(message, ...args);
  }

  info(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.INFO, ...args);
    this._daemonFileLogger.info(message, ...args);
  }

  warn(message: unknown, ...args: unknown[]): void {
    if (message === undefined || message === '') {
      return;
    }
    this.createLogEventByDurationId(message, MetricLogType.WARN, ...args);
    this._daemonFileLogger.warn(message, ...args);
  }

  error(message: unknown, ...args: unknown[]): void {
    this.createLogEventByDurationId(message, MetricLogType.ERROR, ...args);
    this._daemonFileLogger.error(message, ...args);
  }
}

export function configureDaemon() {
  configure(daemonConfiguration);
}
